package it.polimi.jita.cp.block;

import it.polimi.jita.cp.block.co.CapacityOptimator;
import it.polimi.jita.cp.block.co.CapacityOptimizatorInput;
import it.polimi.jita.cp.block.dd.DynamicDecisionMaker;
import it.polimi.jita.cp.block.dd.DynamicDecisionMakerInput;
import it.polimi.jita.cp.block.de.DemandEstimator;
import it.polimi.jita.cp.block.de.DemandEstimatorInput;
import it.polimi.jita.cp.block.pc.PenaltyCalculator;
import it.polimi.jita.cp.block.pc.PenaltyCalculatorInput;
import it.polimi.jita.cp.block.scheduler.Scheduler;
import it.polimi.jita.cp.block.scheduler.SchedulerInput;
import it.polimi.jita.cp.rs.RandomStress;
import it.polimi.jita.cp.rs.RandomStressInput;

import java.util.HashMap;
import java.util.Map;

public class BlockRegister {
	private Map<Class<? extends Input>, Class<? extends Block<?, ?>>> map = new HashMap<>();

	public BlockRegister() {
		registerBlock(DemandEstimatorInput.class, DemandEstimator.class);
		registerBlock(PenaltyCalculatorInput.class, PenaltyCalculator.class);
		registerBlock(CapacityOptimizatorInput.class, CapacityOptimator.class);
		registerBlock(SchedulerInput.class, Scheduler.class);
		registerBlock(RandomStressInput.class, RandomStress.class);
		registerBlock(DynamicDecisionMakerInput.class,
				DynamicDecisionMaker.class);

	}

	protected <I extends Input> void registerBlock(Class<I> inputClass,
			Class<? extends Block<I, ?>> blockClass) {
		map.put(inputClass, blockClass);
	}

	@SuppressWarnings("unchecked")
	public <I extends Input, O extends Output> Block<I, O> getBlock(
			Class<I> input) throws InstantiationException,
			IllegalAccessException {
		return (Block<I, O>) map.get(input).newInstance();
	}
}
